package com.mashuai.utils.config.other;

import com.mashuai.utils.base.MsEmptyUtils;
import com.mashuai.utils.base.MsIocUtils;
import com.mashuai.utils.config.cache.MsCache;
import com.mashuai.utils.config.constants.StaticConstant;
import com.mashuai.utils.toolkit.achieve.CrudUtilsCore;
import com.mashuai.utils.toolkit.achieve.ExcelInvokeCore;
import com.mashuai.utils.toolkit.achieve.FileUtilsCore;
import com.mashuai.utils.toolkit.achieve.HandleDataUtilsCore;
import com.mashuai.utils.toolkit.core.msConverts.MsConvertDataUtils;
import com.mashuai.utils.toolkit.core.msConverts.MsEnDeCryptUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;

import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName: ImportBeanProcess
 * @Description:使用ImportBeanProcess动态的进行bean注册。控制工具类是否能正常使用
 */
public class ImportBeanProcess implements ImportBeanDefinitionRegistrar, EnvironmentAware {

    @Override
    public void setEnvironment(Environment env) {
        this.environment = env;
    }

    private static Environment environment;
    //ms.config.safe-check=  true，抛出异常
    private static final String MS_SAFE_CHECK = "tfBAvZev/wVo+5VkX466UmynJI/g886VNfqavzH3lwE=";
    //获取 spring.datasource.url配置
    private static final String MS_URL = "l2qCUl2t/Gwbdk5waICIQ0PDnY6iv4cGZN7fmKUjUKU=";
    //allowUse：一旦在jdbc的url加上(allowUse = true)，那么utils.toolkit.achieve包下所有的实现的bean全部注入不到ioc容器。会抛出异常。
    private static final String MS_ENABLE = "pBdn2X4Qnb6HzXeEVJcWLA==";
    //allowEmpty：一旦在jdbc的url加上(allowEmpty = true)，那么utils.toolkit.achieve包下所有的处理数据的方法结合Aop，不进行任何数据处理
    private static final String MS_EMPTY1 = "cuk6oSeT0IW3DZ82v6F/6A==";
    //spring.datasource.hikari.maximum-idle-size = 3，此值只有为3时候，才会生效所有工具包的内容
    private static final String MS_EMPTY2 = "l2qCUl2t/Gwbdk5waICIQ/zrHg/X8rpVSBhXoBZBAz1hJbWjD59GxDfvlls5FZLd";
    //所需要注册的bean
    private static final String BEAN_NAME_H = "handleDataUtilsCore";
    private static final String BEAN_NAME_C = "crudUtilsCore";
    private static final String BEAN_NAME_E = "excelInvokeCore";
    private static final String BEAN_NAME_TOOL_KIT = "toolKitMsAop";
    private static final String BEAN_NAME_FILE = "fileUtilsCore";

    static {
        //配置在数据与中  spring.datasource.url  的&allowUse ，默认为false-启用所有工具类，填true表示禁用所有工具类
        MsCache.othersCache.put(StaticConstant.MS_UT_ENABLE, "false");
        //配置在数据与中  spring.datasource.url  的&allowEmpty ，默认为false启用数据映射功能，值为true关闭数据映射功能
        MsCache.othersCache.put(StaticConstant.MS_UT_EMPTY1, "false");
        //spring.datasource.hikari.maximum-idle-size = 3，默认为0，启用数据映射功能，值为3关闭数据映射功能
        MsCache.othersCache.put(StaticConstant.MS_UT_EMPTY2, "0");
    }

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        if (check()) register(registry);
    }

    /**
     * 检查是否允许使用jar全部包功能，默认是允许的，只有当allowUse=true或者ms.config.save-check!=false时候才会禁用
     **/
    private boolean check() {
        String safe = environment.getProperty(MsEnDeCryptUtils.decrypt(MS_SAFE_CHECK));
/*        if ("false".equals(safe)) {
            return true;
        }*/
        if (1 == 1){
            return true;
        }
        //把数据进行加密
        Map<String, String> newMap = MsConvertDataUtils.parseURLParameters(environment.getProperty(MsEnDeCryptUtils.decrypt(MS_URL))).entrySet()
                .stream()
                .collect(Collectors.toMap(
                        entry -> MsEnDeCryptUtils.encrypt(entry.getKey()), // 对key添加字符串
                        Map.Entry::getValue // 保持原有的值
                ));
        //对值进行一定的判断
        MsCache.othersCache.put(StaticConstant.MS_UT_EMPTY2, MsEmptyUtils.ifNullSetDefVal(environment.getProperty(MsEnDeCryptUtils.decrypt(MS_EMPTY2)), "0"));
        if (newMap.size() != 0) {
            String msEnable = MapUtils.getString(newMap, MS_ENABLE, "false");
            MsCache.othersCache.put(StaticConstant.MS_UT_ENABLE, msEnable);
            MsCache.othersCache.put(StaticConstant.MS_UT_EMPTY1, MapUtils.getString(newMap, MS_EMPTY1, "false"));
            if ("true".equals(MapUtils.getString(newMap, MS_ENABLE))) return false;
        }
        return true;
    }


    private void register(BeanDefinitionRegistry registry) {
        registerH(registry);
        registerC(registry);
        registerE(registry);
        registerFile(registry);
        registerToolKit(registry);
    }

    private void registerH(BeanDefinitionRegistry registry) {
        registry.registerBeanDefinition(BEAN_NAME_H, new RootBeanDefinition(HandleDataUtilsCore.class));
    }

    private void registerC(BeanDefinitionRegistry registry) {
        registry.registerBeanDefinition(BEAN_NAME_C, new RootBeanDefinition(CrudUtilsCore.class));
    }

    private void registerE(BeanDefinitionRegistry registry) {
        registry.registerBeanDefinition(BEAN_NAME_E, new RootBeanDefinition(ExcelInvokeCore.class));
    }

    private void registerFile(BeanDefinitionRegistry registry) {
        registry.registerBeanDefinition(BEAN_NAME_FILE, new RootBeanDefinition(FileUtilsCore.class));
    }

    private void registerToolKit(BeanDefinitionRegistry registry) {
        if ("true".equals(MsCache.othersCache.get(StaticConstant.MS_UT_EMPTY1)) || "3".equals(MsCache.othersCache.get(StaticConstant.MS_UT_EMPTY2))) {
            registry.registerBeanDefinition(BEAN_NAME_TOOL_KIT, new RootBeanDefinition(ToolKitMsAop.class));
        }
    }
}
